'use strict';

/**
 * 0.1.1
 * Deferred load js/css file, used for ui-jq.js and Lazy Loading.
 * 
 * @ flatfull.com All Rights Reserved.
 * Author url: #user/flatfull
 */

angular.module('ui.load', []).service('uiLoad', ['$document', '$q', '$timeout',
function($document, $q, $timeout) {

    var loaded = [];
    var promise = false;
    var deferred = $q.defer();

    /**
	 * Chain loads the given sources
	 * @param srcs array, script or css
	 * @returns {*} Promise that will be resolved once the sources has been loaded.
	 */
    this.load = function(srcs) {
        srcs = angular.isArray(srcs) ? srcs: srcs.split(/\s+/);
        var self = this;
        if (!promise) {
            promise = deferred.promise;
        }
        angular.forEach(srcs,
        function(src) {
            promise = promise.then(function() {
                return src.indexOf('.css') >= 0 ? self.loadCSS(src) : self.loadScript(src);
            });
        });
        deferred.resolve();
        return promise;
    }

    /**
	 * Dynamically loads the given script
	 * @param src The url of the script to load dynamically
	 * @returns {*} Promise that will be resolved once the script has been loaded.
	 */
    this.loadScript = function(src) {
        if (loaded[src]) return loaded[src].promise;

        var deferred = $q.defer();
        var script = $document[0].createElement('script');
        script.src = src;
        script.onload = function(e) {
            $timeout(function() {
                deferred.resolve(e);
            });
        };
        script.onerror = function(e) {
            $timeout(function() {
                deferred.reject(e);
            });
        };
        $document[0].body.appendChild(script);
        loaded[src] = deferred;

        return deferred.promise;
    };

    /**
	 * Dynamically loads the given CSS file
	 * @param href The url of the CSS to load dynamically
	 * @returns {*} Promise that will be resolved once the CSS file has been loaded.
	 */
    this.loadCSS = function(href) {
        if (loaded[href]) return loaded[href].promise;

        var deferred = $q.defer();
        var style = $document[0].createElement('link');
        style.rel = 'stylesheet';
        style.type = 'text/css';
        style.href = href;
        style.onload = function(e) {
            $timeout(function() {
                deferred.resolve(e);
            });
        };
        style.onerror = function(e) {
            $timeout(function() {
                deferred.reject(e);
            });
        };
        $document[0].head.appendChild(style);
        loaded[href] = deferred;

        return deferred.promise;
    };
}]);